﻿@model SmartAdmin.WebUI.Data.Models.Log
@{
  /**/

  ViewData["Title"] = "系统日志";
  ViewData["PageName"] = "logs_index";
  ViewData["Heading"] = "<i class='fal fa-ballot-check text-primary'></i>  系统日志";
  ViewData["Category1"] = "系统管理";
  ViewData["PageDescription"] = "";
}
@section HeadBlock {
  <link href="~/css/statistics/chartjs/chartjs.css" rel="stylesheet" />
  <link href="~/css/formplugins/bootstrap-daterangepicker/bootstrap-daterangepicker.css" rel="stylesheet" />

  <link href="~/js/easyui/themes/insdep/easyui.css" rel="stylesheet" asp-append-version="true" />
  <style>
    #test-container {
      overflow-wrap: break-word;
      word-wrap: break-word;
      hyphens: auto;
    }
  </style>
}
<div class="row mb-2">
  <div class="col-sm-12 col-md-8" style="position: relative;height:230px">
    <canvas id='timebar' style="height: 100%;"></canvas>
  </div>
  <div class="col-sm-12 col-md-4" style="position: relative;height:230px">
    <canvas id='levelpie' class="m-auto" style="height: 100%;"></canvas>
  </div>
</div>
<div class="row">
  <div class="col-lg-12 col-xl-12">
    <div id="panel-1" class="panel">
      <div class="panel-hdr">
        <h2>
          系统日志
        </h2>
        <div class="panel-toolbar">
          <button class="btn btn-panel bg-transparent fs-xl w-auto h-auto rounded-0" data-action="panel-collapse" data-toggle="tooltip" data-offset="0,10" data-original-title="Collapse"><i class="fal fa-window-minimize"></i></button>
          <button class="btn btn-panel bg-transparent fs-xl w-auto h-auto rounded-0" data-action="panel-fullscreen" data-toggle="tooltip" data-offset="0,10" data-original-title="Fullscreen"><i class="fal fa-expand"></i></button>
          @*<button class="btn btn-panel bg-transparent fs-xl w-auto h-auto rounded-0" data-action="panel-close" data-toggle="tooltip" data-offset="0,10" data-original-title="Close"><i class="fal fa-times"></i></button>*@
        </div>

      </div>
      <div class="panel-container enable-loader show">
        <div class="loader"><i class="fal fa-spinner-third fa-spin-4x fs-xxl"></i></div>
        <div class="panel-content py-2 rounded-bottom border-faded border-left-0 border-right-0  text-muted bg-faded bg-subtlelight-fade ">
          <div class="row no-gutters align-items-center">
            <div class="col">
              <!-- 开启授权控制请参考 @@if (Html.IsAuthorize("Create") -->

              <div class="btn-group btn-group-sm">
                <button onclick="reload()" class="btn btn-default"> <span class="fal fa-search mr-1"></span> 刷新 </button>
              </div>
            </div>

          </div>

        </div>
        <div class="panel-content">
          <div class="table-responsive">
            <table id="logs_datagrid"></table>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>



@section ScriptsBlock {
  <script src="~/js/dependency/moment/moment.js" asp-append-version="true"></script>
  <script src="~/js/dependency/numeral/numeral.min.js" asp-append-version="true"></script>
  <script src="~/js/formplugins/bootstrap-daterangepicker/bootstrap-daterangepicker.js"></script>
  <script src="~/js/easyui/jquery.easyui.min.js" asp-append-version="true"></script>
  <script src="~/js/easyui/plugins/datagrid-filter.js" asp-append-version="true"></script>
  <script src="~/js/easyui/locale/easyui-lang-zh_CN.js" asp-append-version="true"></script>
  <script src="~/js/easyui/jquery.easyui.component.js" asp-append-version="true"></script>
  <script src="~/js/jquery.extend.formatter.js" asp-append-version="true"></script>
  <script src="~/js/plugin/jquery.serializejson/jquery.serializejson.js" asp-append-version="true"></script>
  <script src="~/js/statistics/chartjs/chartjs.bundle.js"></script>
  <script type="text/javascript">
    //全屏事件
    document.addEventListener('panel.onfullscreen', () => {
      $dg.treegrid('resize');
    });
    //-------NLogLevel---------//
    var levelfiltersource = [{ value: '', text: 'All' }];
    var leveldatasource = [];
    levelfiltersource.push({ value: 'Debug', text: 'Debug' });
    leveldatasource.push({ value: 'Debug', text: 'Debug' });
    levelfiltersource.push({ value: 'Error', text: 'Error' });
    leveldatasource.push({ value: 'Error', text: 'Error' });
    levelfiltersource.push({ value: 'Fatal', text: 'Fatal' });
    leveldatasource.push({ value: 'Fatal', text: 'Fatal' });
    levelfiltersource.push({ value: 'Info', text: 'Info' });
    leveldatasource.push({ value: 'Info', text: 'Info' });
    levelfiltersource.push({ value: 'Trace', text: 'Trace' });
    leveldatasource.push({ value: 'Trace', text: 'Trace' });
    levelfiltersource.push({ value: 'Warn', text: 'Warn' });
    leveldatasource.push({ value: 'Warn', text: 'Warn' });
    //for datagrid Level field  formatter
    function levelformatter(value, row, index) {
      let multiple = false;
      if (value === null || value === '' || value === undefined) {
        return "";
      }
      if (multiple) {
        let valarray = value.split(',');
        let result = leveldatasource.filter(item => valarray.includes(item.value));
        let textarray = result.map(x => x.text);
        if (textarray.length > 0)
          return textarray.join(",");
        else
          return value;
      } else {
        let result = leveldatasource.filter(x => x.value == value);
        if (result.length > 0)
          return result[0].text;
        else
          return value;
      }
    }
    //for datagrid   Level  field filter
    $.extend($.fn.datagrid.defaults.filters, {
      levelfilter: {
        init: function (container, options) {
          var input = $('<select class="easyui-combobox" >').appendTo(container);
          var myoptions = {
            panelHeight: 'auto',
            editable: false,
            data: levelfiltersource,
            onChange: function () {
              input.trigger('combobox.filter');
            }
          };
          $.extend(options, myoptions);
          input.combobox(options);
          input.combobox('textbox').bind('keydown', function (e) {
            if (e.keyCode === 13) {
              $(e.target).emulateTab();
            }
          });
          return input;
        },
        destroy: function (target) {

        },
        getValue: function (target) {
          return $(target).combobox('getValue');
        },
        setValue: function (target, value) {
          $(target).combobox('setValue', value);
        },
        resize: function (target, width) {
          $(target).combobox('resize', width);
        }
      }
    });
    //获取图表数据
    $(async () => {
      var data = await $.get('/Logs/GetChartData');
      console.log(data);
      var ctx = document.getElementById('timebar').getContext('2d');
      var timebarchart = new Chart(ctx, {
        type: 'bar',
        data: {
          labels: Array.from(new Set(data.list.map(item => item.time))),
          datasets: [{
            label: 'Info',
            data: data.list.filter(item => item.level == 'Info').map(item => item.total),
            backgroundColor: '#1dc9b7',
            //borderColor: "rgba(179,181,198,1)",
            //pointBorderColor: "#fff",
            //pointBackgroundColor: "rgba(179,181,198,1)",
          },
          {
            label: 'Trace',
            data: data.list.filter(item => item.level == 'Trace').map(item => item.total),
            backgroundColor: '#2196f3',
            //borderColor: "rgba(179,181,198,1)",
            //pointBorderColor: "#fff",
            //pointBackgroundColor: "rgba(179,181,198,1)",
          },
          {
            label: 'Debug',
            data: data.list.filter(item => item.level == 'Debug').map(item => item.total),
            backgroundColor: '#868e96',
            //borderColor: "rgba(179,181,198,1)",
            //pointBorderColor: "#fff",
            //pointBackgroundColor: "rgba(179,181,198,1)",
          },
          {
            label: 'Warn',
            data: data.list.filter(item => item.level == 'Warn').map(item => item.total),
            backgroundColor: '#ffc241',
            //borderColor: "rgba(179,181,198,1)",
            //pointBorderColor: "#fff",
            //pointBackgroundColor: "rgba(179,181,198,1)",
          },
          {
            label: 'Error',
            data: data.list.filter(item => item.level == 'Error').map(item => item.total),
            backgroundColor: '#fe6bb0',
            //borderColor: "rgba(179,181,198,1)",
            //pointBorderColor: "#fff",
            //pointBackgroundColor: "rgba(179,181,198,1)",
          },
          {
            label: 'Fatal',
            data: data.list.filter(item => item.level == 'Fatal').map(item => item.total),
            backgroundColor: '#e7026e',
            //borderColor: "rgba(179,181,198,1)",
            //pointBorderColor: "#fff",
            //pointBackgroundColor: "rgba(179,181,198,1)",
          }
          ]
        },
        options: {
          legend: { display: false },
          maintainAspectRatio: false,
          responsive: true,
          tooltips: {
            mode: 'index',
            intersect: false
          },
          title: {
            display: true,
            text: '最近3天志情况',
          },
          scales: {
            xAxes: [{
              stacked: true,
              type: "time",
              time: {
                displayFormats: {
                  'hour': 'H',
                }
              }
            }],
            yAxes: [{
              stacked: true,
              ticks: {
                beginAtZero: true,
                stepSize: 20
              }
            }]
          }
        }
      });


      new Chart(document.getElementById("levelpie").getContext('2d'), {
        type: 'doughnut',
        data: {
          labels: data.group.map(item=>item.level),
          datasets: [{
            label: "Population (millions)",
            backgroundColor: ["#1dc9b7", "#2196f3", "#868e96", "#ffc241", "#fe6bb0", "#e7026e"],
            data: data.group.map(item=>item.total)
          }]
        },
        options: {
          maintainAspectRatio: false,
          responsive: false,
          legend: {
            display: true,
            position:'bottom'},
          title: {
            display: true,
            text: '日志分类'
          }
        }
      });
    })


      //是否强制从后台取值
      const REQUIRBACKEND = false;
      //是否开启行内编辑
      const EDITINLINE = true;
      //上传导入参数设定
      const entityname = "Log";
      var log = {};



	   //执行导出下载Excel
	   function exportexcel() {
				const filterRules = JSON.stringify($dg.datagrid('options').filterRules);
				//console.log(filterRules);
				$.messager.progress({ title: '正在执行导出!' });
				let formData = new FormData();
				formData.append('filterRules', filterRules);
				formData.append('sort', 'Id');
				formData.append('order', 'asc');
				$.postDownload('/Logs/ExportExcel', formData).then(res => {
                    $.messager.progress('close');
                    toastr.success('导出成功!');
                }).catch(err => {
                    //console.log(err);
                    $.messager.progress('close');
                    $.messager.alert('失败', err.statusText, 'error');
                });

		}

       var editIndex = undefined;
       //重新加载数据
	   function reload() {
          $dg.datagrid('uncheckAll');
			    $dg.datagrid('reload');
	   }
    //设置日志状态
    function setLogState(id,index) {
      $.get(`/Logs/SetLogState?id=${id}`).done(res => {
        if (res.success) {
          const row = $dg.datagrid('getRows')[index];
          row.IsNew = 1;
          row.IsNotification = 1;
          $dg.datagrid('updateRow', {
            index: index,
            row: {
              Resolved: true,
            }
          });
          $dg.datagrid('refreshRow', index);
        }
      })

    }

    function onClickRow(index, row) {
      const id = row.Id;
      if (row.Exception) {
        bootbox.confirm({
          size:'large',
          title: row.Level,
          message: `<p> ${row.Message}</p>
                    <p> ${row.RequestForm} </p>
                    <p> ${row.Properties } </p>
                   <div  class="p-3 rounded bg-warning-700 text-white mt-3">

                    ${row.Exception}
                                  </div>`,
          callback: function (result) {
            if (result) {
              setLogState(id, index);
            }
          }
        });
      } else {
        bootbox.confirm({
          title: row.Level,
          message: `<p> ${row.Message}</p>
  <p> ${row.RequestForm} </p>
                   <p> ${row.Properties } </p>
              `,
          callback: function (result) {
            if (result) {
              setLogState(id, index);
            }
          }
        });
      }
    }

    //初始化定义datagrid
    var $dg = $('#logs_datagrid');
    $(() => {
      //定义datagrid结构
      $dg.datagrid({
        rownumbers: true,
        checkOnSelect: false,
        selectOnCheck: true,
        idField: 'Id',
        sortName: 'Id',
        sortOrder: 'desc',
        remoteFilter: true,
        singleSelect: true,
        onClickRow: onClickRow,
        method: 'get',
        pagination: true,
        clientPaging: false,
        striped: true,
        pageList: [10, 20, 50, 100, 500],
        filterRules: [{
          field: 'Resolved',
          op: 'equal',
          value: 'false'
        }],
        onHeaderContextMenu: function (e, field) {
          e.preventDefault();
          $(this).datagrid('columnMenu').menu('show', {
            left: e.pageX,
            top: e.pageY
          });
        },
        onBeforeLoad: function () {
          $('.enable-loader').removeClass('enable-loader')
        },
       columns: [[
          {    /*主机名*/
            field: 'MachineName',
            title: '@Html.DisplayNameFor(model => model.MachineName)',
            width: 160,
            hidden: false,
            sortable: true,
            resizable: true
          },
          {   /*时间*/
            field: 'Logged',
            title: '@Html.DisplayNameFor(model => model.Logged)',
            width: 160,
            align: 'right',
            hidden: false,
            formatter: datetimeformatter,
            sortable: true,
            resizable: true
          },
          {    /*级别*/
            field: 'Level',
            title: '@Html.DisplayNameFor(model => model.Level)',
            width: 80,
            hidden: false,
            sortable: true,
            resizable: true,
            align: 'center',
            formatter: function (v) {
              if (v == 'Info') {
                return `<span class="badge badge-info">${v}</span>`
              } else if (v == 'Debug') {
                return `<span class="badge badge-secondary">${v}</span>`
              } else if (v == 'Trace') {
                return `<span class="badge badge-primary">${v}</span>`
              } else if (v == 'Warn') {
                return `<span class="badge badge-warning">${v}</span>`
              } else if (v == 'Error' || v == 'Fatal') {
                return `<span class="badge badge-danger">${v}</span>`
              } else {
                return `<span class="badge badge-light">${v}</span>`
              }
            }
          },
          {    /*信息*/
            field: 'Message',
            title: '@Html.DisplayNameFor(model => model.Message)',
            width: 360,
            hidden: false,
            sortable: true,
            resizable: true
          },
          {    /*异常信息*/
            field: 'RequestIp',
            title: '@Html.DisplayNameFor(model => model.RequestIp)',
            width: 120,
            hidden: false,
            sortable: true,
            resizable: true
          },
          {    /*User-Agent*/
      field: 'UserAgent',
            title: '@Html.DisplayNameFor(model => model.UserAgent)',
            width: 260,
            hidden: false,
            sortable: true,
            resizable: true
          },
          {    /*使用账号*/
            field: 'Identity',
            title: '@Html.DisplayNameFor(model => model.Identity)',
            width: 130,
            hidden: false,
            sortable: true,
            resizable: true
          },
          {  /*已处理*/
            field: 'Resolved',
            title: '<span class="required">@Html.DisplayNameFor(model => model.Resolved)</span>',
            width: 100,
            align: 'center',
            hidden: false,
            formatter: booleanformatter,
            sortable: true,
            resizable: true
          },
          @*{    /*异常信息*/
            field: 'Exception',
            title: '@Html.DisplayNameFor(model => model.Exception)',
            width: 260,
            hidden: false,
            sortable: true,
            resizable: true
          },

          {    /*事件属性*/
            field: 'Properties',
            title: '@Html.DisplayNameFor(model => model.Properties)',
            width: 260,
            hidden: false,
            sortable: true,
            resizable: true
          },

          {    /*日志*/
            field: 'Logger',
            title: '@Html.DisplayNameFor(model => model.Logger)',
            width: 180,
            hidden: false,
            sortable: true,
            resizable: true
          },
          {    /*站点*/
            field: 'Callsite',
            title: '@Html.DisplayNameFor(model => model.Callsite)',
            width: 180,
            hidden: false,
            sortable: true,
            resizable: true
          },*@

        ]]
      })
        .datagrid('enableFilter', [
          {
            field: 'Level',
            type: 'combobox',
            options: {
              data: [
                { value: 'Info', text: 'Info' },
                { value: 'Trace', text: 'Trace' },
                { value: 'Debug', text: 'Debug' },
                { value: 'Warn', text: 'Warn' },
                { value: 'Error', text: 'Error' },
                { value: 'Fatal', text: 'Fatal' }
              ],
              onChange: value => {
                $dg.datagrid('addFilterRule', {
                  field: 'Level',
                  op: 'equal',
                  value: value
                });

                $dg.datagrid('doFilter');
              }
          }
          },
          {
            field: 'Resolved',
            type: 'combobox',
            options: {
              data: [
                { value: 'false', text: '未处理' },
                { value: 'true', text: '已处理' }
              ],
              onChange: value => {
                $dg.datagrid('addFilterRule', {
                  field: 'Resolved',
                  op: 'equal',
                  value: value
                });

                $dg.datagrid('doFilter');
              }
            }
          },
       {     /*注册日期*/
         field: 'Logged',
         type: 'dateRange',
         options: {
           onChange: value => {
             $dg.datagrid('addFilterRule', {
               field: 'RegisterDate',
               op: 'between',
               value: value
             });

             $dg.datagrid('doFilter');
           }
         }
       },
     ])
        .datagrid('load','/Logs/GetData');


    });




  </script>

}
